using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Outpatient.Doman.Smart;
using Outpatient.ErrorCode;
using Outpatient.Infrastructure;
using OutpatientApi.DTO;
using OutpatientApi.Methodimplementation.IServices;
using System.Security.Cryptography;
using System.Text;

namespace OutpatientApi.Methodimplementation.Services
{
    /// <summary>
    /// 用户服务实现类
    /// </summary>
    public class UserService : IUserService
    {
        private readonly EFDbContext _context;
        private readonly ILogger<UserService> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="context">数据库上下文</param>
        /// <param name="logger">日志记录器</param>
        public UserService(EFDbContext context, ILogger<UserService> logger)
        {
            _context = context;
            _logger = logger;
        }

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="loginDto">登录参数</param>
        /// <returns>登录结果</returns>
        public async Task<ApiResult<UserLoginResultDto>> LoginAsync(UserLoginDto loginDto)
        {
            try
            {
                // 记录登录开始日志
                _logger.LogInformation("用户登录开始，用户名：{Username}", loginDto.Username);

                // 参数验证
                if (string.IsNullOrEmpty(loginDto.Username))
                {
                    _logger.LogWarning("登录失败：用户名为空");
                    return new ApiResult<UserLoginResultDto> { msg = "用户名不能为空" };
                }

                if (string.IsNullOrEmpty(loginDto.Password))
                {
                    _logger.LogWarning("登录失败：密码为空");
                    return new ApiResult<UserLoginResultDto> { msg = "密码不能为空" };
                }

                // 查询用户
                var user = await _context.Users
                    .FirstOrDefaultAsync(u => u.Username == loginDto.Username && !u.IsDeleted);

                if (user == null)
                {
                    _logger.LogWarning("登录失败：用户不存在，用户名：{Username}", loginDto.Username);
                    return new ApiResult<UserLoginResultDto> { msg = "用户名或密码错误" };
                }

                // 验证密码
                if (!VerifyPassword(loginDto.Password, user.Password))
                {
                    _logger.LogWarning("登录失败：密码错误，用户名：{Username}", loginDto.Username);
                    return new ApiResult<UserLoginResultDto> { msg = "用户名或密码错误" };
                }

                // 检查用户状态
                if (!user.Status)
                {
                    _logger.LogWarning("登录失败：用户已被禁用，用户名：{Username}", loginDto.Username);
                    return new ApiResult<UserLoginResultDto> { msg = "用户已被禁用" };
                }


                // 生成登录结果
                var result = new UserLoginResultDto
                {
                    UserId = user.UserId,
                    Username = user.Username,
                    Phone = user.Phone,
                    Email = user.Email,
                    Avatar = user.Avatar,
                    CreatedAt = user.CreatedAt,
                    Token = GenerateToken(user.UserId, user.Username),
                    TokenExpireTime = DateTime.Now.AddHours(24) // 24小时过期
                };

                // 记录登录成功日志
                _logger.LogInformation("用户登录成功，用户ID：{UserId}，用户名：{Username}", user.UserId, loginDto.Username);
                
                var apiResult = new ApiResult<UserLoginResultDto>();
                apiResult.success(result, "登录成功");
                return apiResult;
            }
            catch (Exception ex)
            {
                // 记录登录异常日志
                _logger.LogError(ex, "用户登录异常，用户名：{Username}", loginDto.Username);
                return new ApiResult<UserLoginResultDto> { msg = "登录过程中发生异常" };
            }
        }


        /// <summary>
        /// 验证密码
        /// </summary>
        /// <param name="inputPassword">输入的密码</param>
        /// <param name="storedPassword">存储的密码</param>
        /// <returns>验证结果</returns>
        private bool VerifyPassword(string inputPassword, string storedPassword)
        {
            // 这里应该使用加密算法验证密码
            // 为了演示，这里使用简单的字符串比较
            // 实际项目中应该使用BCrypt、PBKDF2等加密算法
            return inputPassword == storedPassword;
        }

        /// <summary>
        /// 生成登录令牌
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="username">用户名</param>
        /// <returns>令牌</returns>
        private string GenerateToken(int userId, string username)
        {
            // 这里应该使用JWT等标准令牌生成方式
            // 为了演示，这里使用简单的字符串拼接
            var tokenData = $"{userId}_{username}_{DateTime.Now.Ticks}";
            using var sha256 = SHA256.Create();
            var hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(tokenData));
            return Convert.ToBase64String(hash);
        }
    }
} 